package android.FiltrosJava;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;

public class TwirlTransform extends AbstractImageBasic{
	protected double shMin, shMax;
	protected int dir;
	
	public TwirlTransform(double shiftMin , double shiftMax, int direction){
		setTwirl(shiftMin , shiftMax, direction);
	}
	
	public void setTwirl(double shiftMin , double shiftMax, int direction){
		shMin = shiftMin;
		shMax = shiftMax;
		dir = direction;		
	}
	
	public BufferedImage applyFilter(BufferedImage dst) {
		BufferedImage src = copiaImagem(dst);
		Graphics2D g2d = dst.createGraphics(); 
		g2d.setColor(Color.black);
		
		
		int[] coord;
		int dimX = src.getWidth();
		int dimY = src.getHeight();
		double ShiftMin = (float) (shMin * Math.PI / 8.0f);
		double ShiftMax = (float) (shMax * Math.PI / 8.0f);
		int xCenter = (int) (dimX / 2.0);
		int yCenter = (int) (dimY / 2.0);
		int MaxRadius = Math.min(xCenter,yCenter);		
		
		WritableRaster raster_src = src.getRaster();
    	WritableRaster raster_dst = dst.getRaster();
    	int numBands = raster_src.getNumBands();
    	int[] imageData = new int[numBands];    	
    	    	
    	int d;
    	if (dir < 0)
    		d = 1;
    	else
    		d = -1;
    	
		for (int y = 0; y < dimY; y++){
			for (int x = 0; x < dimX; x++){
				coord = twirlPoint(x,y,d,xCenter,yCenter,MaxRadius,ShiftMax,ShiftMin);
				if ((coord[0] >= 0) && (coord[0] < dimX) && (coord[1] >= 0) && (coord[1] < dimY)){
					raster_src.getPixel(coord[0],coord[1],imageData);		    			
		    		raster_dst.setPixel(x,y,imageData);						
				}
			}			
		}
		src = null;
		return dst;		
    }
	
	public int[] twirlPoint(int px, int py, int direction, int xCenter, int yCenter, int MaxRadius, double ShiftMax, double ShiftMin){
		int[] points = new int[2];
		
		int x = (int) (px - xCenter);
		int y = (int) (py - yCenter);
		double Radius = (float) Math.sqrt(x * x + y * y);
		double Theta = (float) Math.atan2(x, y);
		double Ratio = (float) (Radius / MaxRadius);
		double seno, coseno;

		if (Ratio > 1.0f){
			points[0] = px;
			points[1] = py;
		}else{
			Theta = (float) (Theta + direction * (Ratio * ShiftMin + (1.0f - Ratio) * ShiftMax));
			seno = (float) Math.sin(Theta);
			coseno = (float) Math.cos(Theta);
			
			x = (int) (Radius * seno);
			y = (int) (Radius * coseno);
			points[0] = (int) (x + xCenter);
			points[1] = (int) (y + yCenter);
		}
		
		return points;		
	}
		

}
